package com.headfirst.StructuralMode.decorator;

import com.headfirst.StructuralMode.decorator.version1.*;
import com.headfirst.StructuralMode.decorator.myenum.CoffeeSize;
import com.headfirst.StructuralMode.decorator.version1.coffee.DarkRoast;
import com.headfirst.StructuralMode.decorator.version1.coffee.Espresso;
import com.headfirst.StructuralMode.decorator.version1.coffee.HouseBlend;
import com.headfirst.StructuralMode.decorator.version1.condiment.Milk;
import com.headfirst.StructuralMode.decorator.version1.condiment.Mocha;
import com.headfirst.StructuralMode.decorator.version1.condiment.Soy;
import com.headfirst.StructuralMode.decorator.version1.condiment.Whip;
import org.junit.Test;

/**
 * 装饰者模式测试程序
 *
 * @author sunhongguang
 * @create 2022-01-22-21:26
 */
public class StarbuzzCoffee {

    @Test
    public void test1() {

        // 一杯浓缩咖啡，不加任何调料品
        Beverage beverage = new Espresso();
        System.out.println(beverage.getDescription() + " $" + beverage.cost());

        // 一杯双倍摩卡奶泡烘焙咖啡
        Beverage beverage1 = new DarkRoast();
        beverage1 = new Mocha(beverage1);
        beverage1 = new Mocha(beverage1);
        beverage1 = new Whip(beverage1);
        System.out.println(beverage1.getDescription() + " $" + beverage1.cost());

//        Beverage beverage2 = new DarkRoast();
//        Mocha mocha = new Mocha(beverage2);
//        Mocha mocha1 = new Mocha(mocha);
//        Whip whip = new Whip(mocha1);
//        System.out.println(whip.getDescription()+" $"+whip.cost());

    }

    @Test
    public void test2() {

        // 一杯中杯浓缩咖啡，加豆奶 $2.14
        Beverage beverage2 = new Espresso();
        beverage2 = new Soy(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

        // 一杯中杯浓缩咖啡，加豆奶 $2.14
        Beverage beverage3 = new Espresso(CoffeeSize.MidSize.getDescription());
        beverage3 = new Soy(beverage3);
        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());

        // 一杯小杯浓缩咖啡，加豆奶 $2.09
        Beverage beverage4 = new Espresso(CoffeeSize.MinSize.getDescription());
        beverage4 = new Soy(beverage4);
        System.out.println(beverage4.getDescription() + " $" + beverage4.cost());

        // 一杯大杯浓缩咖啡，加豆奶 $2.19
        Beverage beverage5 = new Espresso(CoffeeSize.LargeSize.getDescription());
        beverage5 = new Soy(beverage5);
        System.out.println(beverage5.getDescription() + " $" + beverage5.cost());

        System.out.println("----------------");
        // 一杯小杯综合咖啡，加豆浆
        Beverage beverage6 = new HouseBlend(CoffeeSize.MinSize.getDescription());
        beverage6 = new Soy(beverage6);
        System.out.println(beverage6.getDescription() + " $" + beverage6.cost());

        // 一杯中杯综合咖啡，加豆浆
        Beverage beverage7 = new HouseBlend(CoffeeSize.MidSize.getDescription());
        beverage7 = new Soy(beverage7);
        System.out.println(beverage7.getDescription() + " $" + beverage7.cost());
    }

    @Test
    public void test3() {

        // 小杯深焙+牛奶咖啡
        Beverage beverage1 = new DarkRoast(CoffeeSize.MinSize.getDescription());
        beverage1 = new Milk(beverage1);
        System.out.println(beverage1.getDescription() + " $" + beverage1.cost());

        // 中杯深焙+牛奶咖啡
        Beverage beverage2 = new DarkRoast(CoffeeSize.MidSize.getDescription());
        beverage2 = new Milk(beverage2);
        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());

        // 超大杯浓缩+牛奶+双倍摩卡+奶盖 $3.79
        Beverage beverage3 = new Espresso(CoffeeSize.VeryLargeSize.getDescription());
//        beverage3 = new Milk(beverage3);
//        beverage3 = new Mocha(beverage3);
//        beverage3 = new Mocha(beverage3);
//        beverage3 = new Whip(beverage3);
//        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());

        beverage3 = new Whip(new Mocha(new Mocha(new Milk(beverage3))));
        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());


        /**
         * 1.
         * 下面这种装饰之后，返回具体的装饰者类型是不合理的，因为我买的是一杯咖啡，你经过装饰之后，
         * 我的咖啡难道就变成了牛奶? 摩卡? 或者 奶泡? 这显然是不合理的，因为我最后拿到手里的还是一
         * 杯咖啡，而其中的装饰者只是在这里面加了一些调味料而已。
         * 2.
         *  其实也可以想一想现实中的情况，我去奶茶店里买一杯超大杯原味奶茶，我对店员说我想在里面加珍珠和牛奶，
         *  那么店员是这样操作的：首先制作好一杯什么都没有添加的超大杯原味奶茶，然后在这杯超大杯原味奶茶里面加入珍珠，最后在
         *  已经加入珍珠的奶茶里面再添加牛奶，然后拿给了我。从这个过程可知，我最后得到的还是一杯奶茶，只不过在
         *  店员制作这杯奶茶的过程中，对这杯奶茶进行了一系列的装饰（添加各种调味品）的操作。所以中间在添加调味品
         *  的过程中，应该返回的都是原始的奶茶对象，而不是装饰者对象（各种调味品对象）。
         */
//        Milk milk = new Milk(beverage3);
//        Mocha mocha1 = new Mocha(milk);
//        Mocha mocha2 = new Mocha(mocha1);
//        Whip whip = new Whip(mocha2);
//        System.out.println(whip.getDescription() + " $" + whip.cost());
    }
}
